<?php

App::uses('MyInflector', 'Utility');

class ControllerListComponent extends Component {

    public function getList(Array $controllersToExclude = array('PagesController')) {

        $controllersToExclude[] = 'AppController';
        $controllerClasses = array_filter(App::objects('Controller'), function ($controller) use ($controllersToExclude) {
            return !in_array($controller, $controllersToExclude);
        });

        $plugin = App::path('Plugin');
        $plugins = array();
        foreach (CakePlugin::loaded() as $key => $value) {
            $controllersToExclude[] = str_replace('Controller', 'AppController', $value);
        }
        foreach (CakePlugin::loaded() as $key => $value) {
            $plugins[$value] = array_filter(App::objects('Controller', $plugin[0] . $value . DS . 'Controller', false), function ($controller) use ($controllersToExclude) {
                return !in_array($controller, $controllersToExclude);
            });
        }

        $result = array();
$i = 0;
        foreach ($controllerClasses as $controller) {
            $controllerName = str_replace('Controller', '', $controller);
            $result[$i]['plugin'] = NULL;
            $result[$i][0]['name'] = $controllerName;
            $result[$i][0]['displayName'] = MyInflector::acentos(Inflector::humanize(Inflector::underscore($controllerName)));
            $result[$i][0]['actions'] = $this->getActions($controller);
            $i++;
        }

        foreach ($plugins as $p => $controller) {
            if (!empty($controller)) {
                foreach ($controller as $key => $value) {
                    $controllerName = str_replace('Controller', '', $value);
                    $result[$i]['plugin'] = $p;
                    $result[$i][$key]['name'] = $controllerName;
                    $result[$i][$key]['displayName'] = MyInflector::acentos(Inflector::humanize(Inflector::underscore($controllerName)));
                    $result[$i][$key]['actions'] = $this->getActionsPlugin($value, $p);
                    $i++;
                }
            }
        }

        return $result;
    }

    private function getActions($controller) {
        App::uses($controller, 'Controller');
        $methods = get_class_methods($controller);
        $methods = $this->removeParentMethods($methods);
        $methods = $this->removePrivateActions($methods);
        $methods = $this->getActionsTitle($methods);

        return $methods;
    }

    private function getActionsPlugin($controller, $plugin) {
        App::uses($plugin.'AppController', $plugin . '.Controller');
        App::uses($controller, $plugin . '.Controller');
        $methods = get_class_methods($controller);
        $methods = $this->removeParentMethods($methods);
        $methods = $this->removePrivateActions($methods);
        $methods = $this->getActionsTitle($methods);
        return $methods;
    }
    
    private function getActionsTitle($actions){
        $_actions = array();
        if(count($actions)){
            foreach ($actions as $key => $value) {
                $_actions[$key]['title'] = MyInflector::acentos(Inflector::humanize(Inflector::underscore($value)));
                $_actions[$key]['action'] = $value;
            }
        }
        return $_actions;
    }

    private function removeParentMethods(Array $methods) {
        $appControllerMethods = get_class_methods('AppController');
        return array_diff($methods, $appControllerMethods);
    }

    private function removePrivateActions(Array $methods) {
        return array_filter($methods, function ($method) {
            return $method{0} != '_';
        });
    }

}
